﻿using System;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
using Mvc.Validation.Validators;
using web_uchet.Models;
using web_uchet.Security.Enums;
using web_uchet.Security.Interfaces;
using web_uchet.StringResources;
namespace web_uchet.Security
{
    public class ViewUser : IViewUser
    {
        public ViewUser(IUser User,bool GetUserName)
        {
            this._User = User;
            this._Roles = new UserRoleEnum[] { UserRoleEnum.Не_задано, UserRoleEnum.Не_задано, UserRoleEnum.Не_задано };
            this._UserName = GetUserName ? Membership.GetUser(User.ИД_Пользователя).UserName : String.Empty;
        }
        public ViewUser()
        {
            this._User = new Пользователь();
            
            this._Roles = new UserRoleEnum[] { UserRoleEnum.Не_задано, UserRoleEnum.Не_задано, UserRoleEnum.Не_задано };
        }
        private IUser _User;
        //public IUser Admin
        //{
        //    get
        //    {
        //        return this._Admin;
        //    }
        //}
        private string _Password1;
        private string _Password2;
        private string _email;
        private string _PQuestion;
        private string _UserName;
        private string _PAnswer;
        private UserRoleEnum[] _Roles;
        public UserRoleEnum[] Roles
        {
            get
            {
                return this._Roles;        
            }
        }
        [NotNullOrEmptyValidator(MessageTemplate = "Выберите обязанности")]
        public string Role1
        {
            get
            {
                if (this._Roles.Length > 0)
                    return this._Roles[0].ToString();
                else return UserRoleEnum.Не_задано.ToString();
            }
            set
            {
                UserRoleEnum EVal = (UserRoleEnum)Enum.Parse(typeof(UserRoleEnum), value);

                //if (EVal != UserRoleEnum.Не_задано && !this._Roles.Contains(EVal))
                //{
                //    if (this._Roles[0] != UserRoleEnum.Не_задано)
                //        System.Web.Security.Roles.RemoveUserFromRole(this.UserName, this._Roles[0].ToString());

                //    System.Web.Security.Roles.AddUserToRole(this.UserName, value);
                //}
                //else
                //    if (this._Roles[0] != UserRoleEnum.Не_задано && EVal == UserRoleEnum.Не_задано)
                //        System.Web.Security.Roles.RemoveUserFromRole(this.UserName, this._Roles[0].ToString());
                this._Roles[0] = EVal;
            }
        }
        public string Role2
        {
            get
            {
                if (this._Roles.Length > 1)
                    return this._Roles[1].ToString();
                else return UserRoleEnum.Не_задано.ToString();
            }
            set
            {
                UserRoleEnum EVal = (UserRoleEnum)Enum.Parse(typeof(UserRoleEnum), value);

                //if (EVal != UserRoleEnum.Не_задано && !this._Roles.Contains(EVal))
                //{
                //    if (this._Roles[1] != UserRoleEnum.Не_задано)
                //        System.Web.Security.Roles.RemoveUserFromRole(this.UserName, this._Roles[1].ToString());

                //    System.Web.Security.Roles.AddUserToRole(this.UserName, value);
                //}
                //else
                //    if (this._Roles[1] != UserRoleEnum.Не_задано && EVal == UserRoleEnum.Не_задано)
                //        System.Web.Security.Roles.RemoveUserFromRole(this.UserName, this._Roles[1].ToString());
                this._Roles[1] = EVal;
            }
        }
        public string Role3
        {
            get
            {
                if (this._Roles.Length > 2)
                    return this._Roles[2].ToString();
                else return UserRoleEnum.Не_задано.ToString();
            }
            set
            {
                UserRoleEnum EVal = (UserRoleEnum)Enum.Parse(typeof(UserRoleEnum), value);

                //if (EVal != UserRoleEnum.Не_задано && !this._Roles.Contains(EVal))
                //{
                //    if (this._Roles[2] != UserRoleEnum.Не_задано)
                //        System.Web.Security.Roles.RemoveUserFromRole(this.UserName, this._Roles[2].ToString());

                //    System.Web.Security.Roles.AddUserToRole(this.UserName, value);
                //}
                //else
                //    if (this._Roles[2] != UserRoleEnum.Не_задано && EVal == UserRoleEnum.Не_задано)
                //        System.Web.Security.Roles.RemoveUserFromRole(this.UserName, this._Roles[2].ToString());
                this._Roles[2] = EVal;
            }
        }
        //<summary>
        //Gets the Company Of The Admin
        //</summary>
        public ICompany Company
        {
            get
            {
                return this._User.Компания as ICompany;
            }
        }
        //{
        //    get { return this._User.Место_Работы; }
        //    set { this._User.Место_Работы = value; }
        //}
        [NotNullOrEmptyValidator(MessageTemplate="Выберите место работы")]
        public int WorkplaceID { get; set; }
        [StringLengthValidator(45, MessageTemplate = ValidationStringResources.StringLength45ValidationMessage)]
        [NotNullOrEmptyValidator(MessageTemplate="Введите ФИО работника")]
        public string RealName
        {
            get { return this._User.Имя_Настоящее; }
            set
            {
                if (value == null) this._User.Имя_Настоящее = string.Empty;
                else
                    this._User.Имя_Настоящее = value;
            }
        }
        [StringLengthValidator(45, MessageTemplate = ValidationStringResources.StringLength45ValidationMessage)]
        public string Def1
        {
            get { return this._User.Описание1; }
            set
            {
                if (value == null) this._User.Описание1 = string.Empty;
                else
                    this._User.Описание1 = value;
            }
        }
        [StringLengthValidator(45, MessageTemplate = ValidationStringResources.StringLength45ValidationMessage)]
        public string Def2
        {
            get { return this._User.Описание2; }
            set
            {
                if (value == null) this._User.Описание2 = string.Empty;
                else
                    this._User.Описание2 = value;
            }
        }
        [StringLengthValidator(45, MessageTemplate = ValidationStringResources.StringLength45ValidationMessage)]
        public string Def3 { get { return this._User.Описание3; } 
            set {
                if (value == null) this._User.Описание3 = string.Empty;
                else
                    this._User.Описание3 = value;
            }
        }
        [RegularExpressionValidator( 
            MessageTemplate = "Пароль должен содержать хотя бы один не алфавитно цифровой символ, например: $,#,%,^,&,* и т.п.",
            Pattern = @"^.*[^a-zA-Z0-9_]{1}.*$")]
        [StringLengthValidator(7, 20, MessageTemplate = "Длина пароля от 7 до 20 символов,")]
        [PropertyComparisonValidator("Password2", ComparisonOperator.Equal,
            MessageTemplate = "Пароли должны совпадать")]
        [NotNullOrEmptyValidator(MessageTemplate = "Введите пароль")]
        public string Password1
        {
            get
            {
                return this._Password1;
            }
            set
            {
                if (value == null) this._Password1 = string.Empty;
                else
                this._Password1 = value;
            }
        }
        //[RegularExpressionValidator(
        //    MessageTemplate = "Пароль должен содержать хотя бы один не алфавитно цифровой символ, например: $,#,%,^,&,* и т.п.",
        //    Pattern = @"^.*[^a-zA-Z0-9_]{1}.*$")]
        //[StringLengthValidator(7, 20, MessageTemplate = "Длина пароля от 7 до 20 символов,")]
        //[PropertyComparisonValidator("Password1", ComparisonOperator.Equal,
        //    MessageTemplate = "Пароли должны совпадать")]
        //[NotNullOrEmptyValidator(MessageTemplate = "Введите подтверждение пароля")]
        public string Password2
        {
            get
            {
                return this._Password2;
            }
            set
            {
                if (value == null) this._Password2 = string.Empty;
                else
                this._Password2 = value;
            }
        }
        [RegularExpressionValidator(MessageTemplate = "Введите корректный e-mail", Pattern = Mvc.Validation.ValidationUtils.EmailPattern)] //
        public string email
        {
            get
            {
                return this._email;
            }
            set
            {
                this._email = value;
            }
        }
        [NotNullOrEmptyValidator(MessageTemplate = "Введите секретный вопрос")]
        public string PQuestion
        {
            get
            {
                return this._PQuestion;
            }
            set
            {
                this._PQuestion = value;
            }
        }
        [NotNullOrEmptyValidator(MessageTemplate = "Введите имя пользователя")]
        [RemoteValidator(MessageTemplate = "Такое имя пользователя уже существует, введите другое",
        ValidatorType = typeof(AlwaysTrueValidator),
        ServerMethod = "/Account/UserNotExists?rand=1", IsPost = false)] //TODO: make a random number to prevent IE caching
        public string UserName
        {
            get
            {
                return this._UserName;
            }
            set
            {
                this._UserName = value;
            }
        }
        [NotNullOrEmptyValidator(MessageTemplate = "Введите секретный ответ")]
        public string PAnswer
        {
            get
            {
                return this._PAnswer;
            }
            set
            {
                this._PAnswer = value;
            }
        }

    }
    public class UserOperationsProvider:IUserOperationsProvider
    {
        private const float StartAccount = 5;
        private web_uchet.Models.ModelWebUchetCon _Context;
        public UserOperationsProvider()
        {
            this._Context = new ModelWebUchetCon(ModelWebUchetCon.SingleToneConnection);
        }
        #region IUserOperationsProvider Members

        public IViewUser GetUserView(string UserName)
        {
            MembershipUser NeededUser=UserName!=string.Empty? Membership.GetUser(UserName):Membership.GetUser();
            int CurUserID=Convert.ToInt32(NeededUser.ProviderUserKey);
            
            Пользователь NeededUser1=this._Context.Пользователи.Include("Компания").Include("Место_Работы").
                FirstOrDefault(e => e.ИД_Пользователя == CurUserID);
            return new ViewUser(NeededUser1 as IUser,false);
        }

        public LoginResult LoginUser(string UserName, string Password, bool rememberMe)
        {
            if (Membership.ValidateUser(UserName, Password))
            {
                IViewUser UserView = this.GetUserView(UserName);
                if (UserView.Company.Счет > 0)
                {
                    FormsAuthentication.SetAuthCookie(UserName, rememberMe);
                    UserView.Company.Дата_Послед_Активн = DateTime.Now;
                    this._Context.SaveChanges(true);
                    FormsAuthentication.RedirectFromLoginPage(UserName, rememberMe);
                    return LoginResult.Success;
                }
                else return LoginResult.LowAccount;
            }
            else return LoginResult.Fail;

        }
        public void LogOut()
        {
            FormsAuthentication.SignOut();
        }

        public bool IsCurrentUserAnonymous()
        {
            return !HttpContext.Current.User.Identity.IsAuthenticated;
        }

        public MembershipCreateStatus CreateUser(IViewUser User,bool LogOn)
        {
            try
            {
                MembershipCreateStatus MCStatus;
                MembershipUser CreatedUser= Membership.CreateUser(User.UserName, User.Password1, User.email, User.PQuestion, User.PAnswer, true, out MCStatus);
                if(User.Roles[0]!=UserRoleEnum.Не_задано)
                Roles.AddUserToRole(CreatedUser.UserName, User.Roles[0].ToString());
                if (User.Roles[1] != UserRoleEnum.Не_задано)
                    Roles.AddUserToRole(CreatedUser.UserName, User.Roles[1].ToString());
                if (User.Roles[2] != UserRoleEnum.Не_задано)
                    Roles.AddUserToRole(CreatedUser.UserName, User.Roles[2].ToString()); 

                if (MCStatus != MembershipCreateStatus.Success) return MCStatus;
                int CurrentAdminID = Convert.ToInt32(Membership.GetUser().ProviderUserKey);
                int NewUserID=Convert.ToInt32(CreatedUser.ProviderUserKey);
                Пользователь CurrentAdminПользователь=this._Context.Пользователи.Include("Компания").First(e=>e.ИД_Пользователя==CurrentAdminID);
                this._Context.AddToПользователи(new Пользователь {Имя_Настоящее=User.RealName,
                                                                  ИД_Пользователя = NewUserID,
                                                                  Компания=CurrentAdminПользователь.Компания,
                                                                  Место_Работы=
                                                                  this._Context.Места_Работы.First(e => e.ИД_Места_Работы == User.WorkplaceID),
                                                                  Описание1=User.Def1,
                                                                  Описание2=User.Def2,
                                                                  Описание3=User.Def3,
                                                                  ASPNetUser=this._Context.ASPNetUsers.First(e => e.UserID == NewUserID),
                });
                this._Context.SaveChanges(true);
                if (LogOn) FormsAuthentication.SetAuthCookie(User.UserName,false);
                return MCStatus;
            }
            catch
            {
                Membership.DeleteUser(User.UserName,true);
                return MembershipCreateStatus.UserRejected;
            }
        }

        public bool IsUserInRole(string UserName, UserRoleEnum Role)
        {
            return Roles.IsUserInRole(UserName, Enum.GetName(typeof(UserRoleEnum), Role));
        }

        public bool IsUserInRole(IUser User, UserRoleEnum Role)
        {
            return Roles.IsUserInRole(Membership.GetUser(
                User.ИД_Пользователя).UserName, Enum.GetName(typeof(UserRoleEnum), Role));
        }

        public UpdateUserResult UpdateUser(IViewUser User)
        {
            throw new NotImplementedException();
            try
            {
                this._Context.Attach(User as Пользователь);
                this._Context.SaveChanges(true);
                return UpdateUserResult.Success;
            }
            catch (Exception ex) { throw ex; return UpdateUserResult.Fail; }
        }

        public void ChangePassword(ChangePassword Changes)
        {
            if (Membership.ValidateUser(Changes.UserName, Changes.currentPassword))
            Membership.GetUser(Changes.UserName).ChangePassword(Changes.currentPassword, Changes.newPassword);
        }

        public void AddCompany(IViewNewCompany ViewNewCompany)
        {
            MembershipCreateStatus MCStatus;
            MembershipUser NewAdmin= Membership.CreateUser(ViewNewCompany.UserName, ViewNewCompany.Password1, ViewNewCompany.email,
                ViewNewCompany.PQuestion, ViewNewCompany.PAnswer, true, out MCStatus);
            Roles.AddUserToRole(ViewNewCompany.UserName, Enum.GetName(typeof(UserRoleEnum), UserRoleEnum.Администратор));
            ViewNewCompany.Admin.ИД_Пользователя=Convert.ToInt32(NewAdmin.ProviderUserKey);
            ViewNewCompany.Admin.ASPNetUser =
                this._Context.ASPNetUsers.Where(e => e.UserID == ViewNewCompany.Admin.ИД_Пользователя).First();            
            this._Context.AddToПользователи(ViewNewCompany.Admin as Пользователь);

            MembershipUser NewEmptyUser = Membership.CreateUser(ViewNewCompany.UserName + "No", Membership.GeneratePassword(50, 20));
            NewEmptyUser.IsApproved = false;
            Roles.AddUserToRoles(NewEmptyUser.UserName,new string[]{"Менеджер","Исполнитель"});
            Пользователь EmptyUser = new Пользователь() { Имя_Настоящее = "Нет", ИД_Пользователя = Convert.ToInt32(NewEmptyUser.ProviderUserKey)};
            EmptyUser.ASPNetUserReference.EntityKey = 
                new System.Data.EntityKey("ModelWebUchetCon.ASPNetUsers", "UserID", Convert.ToInt32(NewEmptyUser.ProviderUserKey));
            this._Context.AddToПользователи(EmptyUser);

            this._Context.AddToКомпании(ViewNewCompany.Company as Компания);
            Место_Работы EmptyWorkPlace = new Место_Работы() { Название = "Нет", Доп_Информация="Рабочее место по-умолчанию",Компания = ViewNewCompany.Company as Компания };
            Клиент EmptyClient = new Клиент() { Имя = "Нет", Описание = "Клиент по-умолчанию", Компания = ViewNewCompany.Company as Компания };            

            this._Context.AddToМеста_Работы(EmptyWorkPlace);
            this._Context.AddToКлиенты(EmptyClient);
            ViewNewCompany.Admin.Место_Работы = EmptyWorkPlace;
            ViewNewCompany.Admin.Компания = ViewNewCompany.Company as Компания;
            EmptyUser.Место_Работы = EmptyWorkPlace;
            EmptyUser.Компания=ViewNewCompany.Company as Компания;
            ViewNewCompany.Company.Счет = UserOperationsProvider.StartAccount;

            Услуга_Компании EmptyУслуга=new Услуга_Компании(){Название="Нет",Компания=ViewNewCompany.Company,Цена_По_Умолчанию=0,
            Валюта=this._Context.Валюты.First()};
            this._Context.AddToУслуги_Компаний(EmptyУслуга);

            this._Context.SaveChanges(true);
            this.LoginUser(ViewNewCompany.UserName, ViewNewCompany.Password1, true);
        }

        public web_uchet.ViewModels.ViewКомпания GetUsersCompany(string UserName, string Pass)
        {
            if (Membership.ValidateUser(UserName,Pass))
            {
                MembershipUser User = Membership.GetUser(UserName);
                int UserID=Convert.ToInt32(User.ProviderUserKey);
                return new web_uchet.ViewModels.ViewКомпания(
                    this._Context.Пользователи.Include("Компания").First(e=>e.ИД_Пользователя==UserID).Компания);
            }
            else return null;
        }
        public web_uchet.Models.Компания GetUsersCompany(int UserID)
        {
                return (
                    this._Context.Пользователи.Include("Компания").First(e=>e.ИД_Пользователя==UserID).Компания);
        }

        public void SetCompanyAccount(int CompanyID, string Amount)
        {
            this._Context.Компании.First(e => e.ИД_Компании == CompanyID)
                .Счет += Convert.ToSingle(Amount, CultureInfo.InvariantCulture);
            this._Context.SaveChanges();
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="WorkPlaceID">Which workplace to select by default</param>
        /// <returns></returns>
        public SelectList GetCurrentCompanyWorkPlacesList(int? WorkPlaceID)
        {
            ///Implicitly it means that this method can be called only by admin
            MembershipUser CompanyAdmin = Membership.GetUser();
            int CompanyAdminID= Convert.ToInt32(CompanyAdmin.ProviderUserKey);
            if (WorkPlaceID.HasValue)
                return new SelectList(
                    this._Context.Пользователи.Include("Компания.Места_Работы").First(e => e.ИД_Пользователя == CompanyAdminID).
                    Компания.Места_Работы.ToList(), "ИД_Места_Работы", "Название", WorkPlaceID.Value);  
            else
            return new SelectList(
                this._Context.Пользователи.Include("Компания.Места_Работы").First(e => e.ИД_Пользователя == CompanyAdminID).
                Компания.Места_Работы.ToList(),"ИД_Места_Работы","Название");                    
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="WorkPlaceID">Which workplace to select by default</param>
        /// <returns></returns>
        public SelectList GetCompanyWorkPlacesList(int CompanyID, int? WorkPlaceID)
        {
            if (WorkPlaceID.HasValue)
                return new SelectList(
                    this._Context.Места_Работы.Where(wp => wp.Компания.ИД_Компании == CompanyID)
                        .ToList(), "ИД_Места_Работы", "Название", WorkPlaceID.Value);
            else
                return new SelectList(
                    this._Context.Места_Работы.Where(wp => wp.Компания.ИД_Компании == CompanyID).ToList(), 
                    "ИД_Места_Работы", "Название");
        }

        public SelectList GetUserRolesList(string Role)
        {
            if (Role!=null)
            return new SelectList(new SelectListItem[] {
                                            new SelectListItem(){Value=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Не_задано),
                                                                 Text=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Не_задано)},
                                            new SelectListItem(){Value=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Исполнитель),
                                                                 Text=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Исполнитель)},
                                            new SelectListItem(){Value=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Администратор),
                                                                 Text=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Администратор)},
                                            new SelectListItem(){Value=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Менеджер),
                                                                 Text=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Менеджер)},
                                            new SelectListItem(){Value=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Просмотр),
                                                                 Text=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Просмотр)},                                           

            }, "Value", "Text",Role);
            else return new SelectList(new SelectListItem[] {
                                            new SelectListItem(){Value=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Не_задано),
                                                                 Text=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Не_задано)},
                                            new SelectListItem(){Value=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Исполнитель),
                                                                 Text=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Исполнитель)},
                                            new SelectListItem(){Value=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Администратор),
                                                                 Text=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Администратор)},
                                            new SelectListItem(){Value=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Менеджер),
                                                                 Text=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Менеджер)},
                                            new SelectListItem(){Value=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Просмотр),
                                                                 Text=Enum.GetName(typeof(UserRoleEnum),UserRoleEnum.Просмотр)},

            }, "Value", "Text");
        }

        public SelectList GetCompanysEmployees(int CompanyID,int? EmployeeID)
        {
            //int UserCompanyID = Convert.ToInt32(User.КомпанияReference.EntityKey.EntityKeyValues.First(e => e.Key == "ИД_Компании").Value);
            var UserList = this._Context.Пользователи.Include("Компания")
                .Where(e => e.Компания.ИД_Компании == CompanyID).OrderBy(e=>e.Имя_Настоящее).ToList();
            if (EmployeeID.HasValue)
                return new SelectList(UserList, "ИД_Пользователя", "Имя_Настоящее", EmployeeID.Value);  
            else
            return new SelectList(UserList, "ИД_Пользователя", "Имя_Настоящее");  
        }
        //Dirty implementation of role selector:
        public SelectList GetCompanysManagers(int CompanyID, int? EmployeeID)
        {
            if (Roles.RoleExists("Менеджер"))
            {
                //int UserCompanyID = User.Компания.ИД_Компании;
                var UserList = this._Context.Пользователи.Include("Компания").Include("ASPNetUser")
                    .Where(e => e.Компания.ИД_Компании == CompanyID).OrderBy(e => e.Имя_Настоящее).
                   ToList().Where(e => Roles.IsUserInRole(e.ASPNetUser.UserName, "Менеджер"));
                if (EmployeeID.HasValue)
                    return new SelectList(UserList, "ИД_Пользователя", "Имя_Настоящее", EmployeeID.Value);
                else
                    return new SelectList(UserList, "ИД_Пользователя", "Имя_Настоящее");  
            }
            else throw new InvalidOperationException("Роль 'Менеджер' отсутствует в хранилище");
        }

        public SelectList GetCompanysExecutives(int CompanyID, int? EmployeeID)
        {
            if (Roles.RoleExists("Исполнитель"))
            {
                //int UserCompanyID = User.Компания.ИД_Компании;
                var UserList = this._Context.Пользователи.Include("Компания").Include("ASPNetUser")
                    .Where(e => e.Компания.ИД_Компании == CompanyID).OrderBy(e => e.Имя_Настоящее).
                    ToList().Where(e => Roles.IsUserInRole(e.ASPNetUser.UserName, "Исполнитель"));

                if (EmployeeID.HasValue)
                    return new SelectList(UserList, "ИД_Пользователя", "Имя_Настоящее", EmployeeID.Value);
                else
                    return new SelectList(UserList, "ИД_Пользователя", "Имя_Настоящее");  
            }
            else throw new InvalidOperationException("Роль 'Исполнитель' отсутствует в хранилище");
        }

        public SelectList GetCompanysAdmins(int CompanyID, int? EmployeeID)
        {
            if (Roles.RoleExists("Администратор"))
            {
                //int UserCompanyID = Convert.ToInt32(User.КомпанияReference.EntityKey.EntityKeyValues.First(e => e.Key == "ИД_Компании").Value);
                var UserList = this._Context.Пользователи.Include("Компания").Include("ASPNetUser")
                    .Where(e => e.Компания.ИД_Компании == CompanyID).OrderBy(e => e.Имя_Настоящее).
                    ToList().Where(e => Roles.IsUserInRole(e.ASPNetUser.UserName, "Администратор"));
                if (EmployeeID.HasValue)
                    return new SelectList(UserList, "ИД_Пользователя", "Имя_Настоящее", EmployeeID.Value);
                else
                    return new SelectList(UserList, "ИД_Пользователя", "Имя_Настоящее");  
            }
            else throw new InvalidOperationException("Роль 'Администратор' отсутствует в хранилище");
        }
        public SelectList GetUserCompanysClients(int CompanyID, int? EmployeeID)
        {
                //int UserCompanyID = Convert.ToInt32(User.КомпанияReference.EntityKey.EntityKeyValues.First(e => e.Key == "ИД_Компании").Value);
            var UserList = this._Context.Клиенты.Include("Компания")
                    .Where(e => e.Компания.ИД_Компании == CompanyID).OrderBy(e => e.Имя).
                    ToList();
            if (EmployeeID.HasValue)
                return new SelectList(UserList, "ИД_Клиент", "Имя", EmployeeID.Value);
            else
                return new SelectList(UserList, "ИД_Клиент", "Имя");  
        }

        public bool UserNotExistst(string UserName)
        {
            if (this._Context.ASPNetUsers.Where(e => e.UserName == UserName).Count() == 0)
                return true;
            else return false;
        }

        public web_uchet.Security.ProgramContext GetMasterPageData(int CurrentUserID)
        {
            ASPNetUser ASPNetUserInformation =
            this._Context.ASPNetUsers.Include("Пользователь.Компания").First(e => e.UserID == CurrentUserID);

            string[] UsersRoles= Roles.GetRolesForUser(ASPNetUserInformation.UserName);
            //UserRoleEnum Role=UserRoleEnum.UnKnown;
            //    if (UsersRoles.Contains("Администратор")) Role= UserRoleEnum.Администратор;
            //    else
            //    if (UsersRoles.Contains("Менеджер")) Role= UserRoleEnum.Менеджер;
            //    else
            //    if (UsersRoles.Contains("Исполнитель")) Role= UserRoleEnum.Исполнитель;
            //    else
            //    if (UsersRoles.Contains("Просмотр")) Role= UserRoleEnum.Просмотр;

            return new web_uchet.Security.ProgramContext() 
            { 
                UserName = ASPNetUserInformation.UserName,
              UserRealName = ASPNetUserInformation.Пользователь.Имя_Настоящее,
              CompanyName = ASPNetUserInformation.Пользователь.Компания.Название,
              CompanyID=ASPNetUserInformation.Пользователь.Компания.ИД_Компании,
              CompanyAccount=ASPNetUserInformation.Пользователь.Компания.Счет,
              ComanyMessage=ASPNetUserInformation.Пользователь.Компания.Сообщение,
              Roles = UsersRoles.Select(e=>(UserRoleEnum)Enum.Parse(typeof(UserRoleEnum),e)).ToArray(),
              UserID = CurrentUserID
            };
        }
        #endregion
    }
    //<summary>
    //Класс для регистрации и показа новой компании
    //</summary>
    public class ViewNewCompany : IViewNewCompany
    {
        public ViewNewCompany()
        {
            this._Company = new Компания();
            this._Admin = new Пользователь();
        }
        //Компания
        private Компания _Company;
        public Компания Company { get { return this._Company; } }
        //Ее админ - человек который регистрирует ее
        private Пользователь _Admin;
        public Пользователь Admin { get { return this._Admin; } set { this._Admin = value; } }

        #region "Company fields"
        [NotNullOrEmptyValidator(MessageTemplate = "Введите название компании")]
        //[ClientID("Название")]
        public string Название { get { return this._Company.Название; }
            set { this._Company.Название = value; }        }
        [NotNullOrEmptyValidator(MessageTemplate = "Введите ФИО Представителя")]
        //[ClientID("ФИО_Представителя")]
        public string ФИО_Представителя { get { return this._Company.ФИО_Представителя; }
            set { this._Company.ФИО_Представителя = value; }}
        [NotNullOrEmptyValidator(MessageTemplate = "Введите контакты компании")]
        
        //[ClientID("Контакты")]
        [StringLengthValidator(100,MessageTemplate="Контакты должны иметь длину не более 100 символов")]
        public string Контакты { get { return this._Company.Контакты; }
            set
            {
                if (value == null) this._Company.Контакты = string.Empty;
                else
                    this._Company.Контакты = value;
            }
        }
        #endregion
        #region "Admin fields"
        [NotNullOrEmptyValidator(MessageTemplate = "Введите настоящее ФИО пользователя")]
        //[ClientID("Имя_Настоящее")]
        public string Имя_Настоящее { get { return this._Admin.Имя_Настоящее; }
            set { this._Admin.Имя_Настоящее = value; }}
        public string Описание1
        {
            get { return this._Admin.Описание1; }
            set { this._Admin.Описание1 = value; }
        }
        #endregion
        private string _UserName;
        [NotNullOrEmptyValidator(MessageTemplate="Введите имя пользователя главы компании")]
        [RemoteValidator(MessageTemplate = "Такое имя пользователя уже существует, введите другое",
        ValidatorType = typeof(AlwaysTrueValidator),
        ServerMethod = "/Account/UserNotExists", IsPost = false)]
        public string UserName { get { return this._UserName; } set { this._UserName = value; } }

        private string _Password1;
        [RegularExpressionValidator(
            MessageTemplate = "Пароль должен содержать хотя бы один не алфавитно цифровой символ, например: $,#,%,^,&,* и т.п.",
            Pattern = @"^.*[^a-zA-Z0-9_]{1}.*$")]
        [StringLengthValidator(7, 20, MessageTemplate = "Длина пароля от 7 до 20 символов,")]
        [PropertyComparisonValidator("Password2", ComparisonOperator.Equal,
            MessageTemplate = "Пароли должны совпадать")]
        [NotNullOrEmptyValidator(MessageTemplate = "Введите пароль")]
        //[ClientID("Password1")]
        public string Password1 { get { return this._Password1; }
            set
            {
                if (value == null) this._Password1 = string.Empty;
                else _Password1 = value;
            }
        }

        private string _Password2;
        [RegularExpressionValidator(
            MessageTemplate = "Пароль должен содержать хотя бы один не алфавитно цифровой символ, например: $,#,%,^,&,* и т.п.",
            Pattern = @"^.*[^a-zA-Z0-9_]{1}.*$")]
        [StringLengthValidator(7, 20, MessageTemplate = "Длина пароля от 7 до 20 символов,")]
        [PropertyComparisonValidator("Password1", ComparisonOperator.Equal,
            MessageTemplate = "Пароли должны совпадать")]
        [NotNullOrEmptyValidator(MessageTemplate = "Введите подтверждение пароля")]
        //[ClientID("Password2")]
        public string Password2
        {
            get { return this._Password2; }
            set
            {
                if (value == null) this._Password2 = string.Empty;
                else _Password2 = value;
            }
        }

        [RegularExpressionValidator(MessageTemplate = "Введите корректный e-mail", Pattern = @"^.+@.+\..+$")]
        [NotNullOrEmptyValidator(MessageTemplate = "Введите корректный e-mail")]
        //[ClientID("email")]
        public string email { get; set; }

        [NotNullOrEmptyValidator(MessageTemplate = "Введите секретный вопрос")]
        //[ClientID("PQuestion")]
        public string PQuestion { get; set; }

        private string _PAnswer;
        [NotNullOrEmptyValidator(MessageTemplate = "Введите секретный ответ")]
        //[ClientID("PAnswer")]
        public string PAnswer
        {
            get { return this._PAnswer; }
            set { this._PAnswer = value; }
        }
    }
    public class ChangePassword
    {
        private string _newPassword;
        [NotNullOrEmptyValidator(MessageTemplate = "Введите имя пользователя")]
        public string UserName { get; set; }
        [NotNullOrEmptyValidator(MessageTemplate = "Введите текущий пароль")]
        public string currentPassword { get; set; }
        [RegularExpressionValidator(
        MessageTemplate = "Пароль должен содержать хотя бы один не алфавитно цифровой символ, например: $,#,%,^,&,* и т.п.",
        Pattern = @"^.*[^a-zA-Z0-9_]{1}.*$")]
        [StringLengthValidator(7, 20, MessageTemplate = "Длина пароля от 7 до 20 символов,")]
        [PropertyComparisonValidator("confirmPassword", ComparisonOperator.Equal,
            MessageTemplate = "Пароли должны совпадать")]
        [NotNullOrEmptyValidator(MessageTemplate = "Введите пароль")]
        public string newPassword
        {
            get { return this._newPassword; }
            set
            {
                if (value == null) this._newPassword = string.Empty;
                else _newPassword = value;
            }
        }
        [RegularExpressionValidator(
        MessageTemplate = "Пароль должен содержать хотя бы один не алфавитно цифровой символ, например: $,#,%,^,&,* и т.п.",
        Pattern = @"^.*[^a-zA-Z0-9_]{1}.*$")]
        [StringLengthValidator(7, 20, MessageTemplate = "Длина пароля от 7 до 20 символов,")]
        [PropertyComparisonValidator("newPassword", ComparisonOperator.Equal,
            MessageTemplate = "Пароли должны совпадать")]
        [NotNullOrEmptyValidator(MessageTemplate = "Введите пароль")]
        public string confirmPassword { get; set; }
    }
    public class ForgotPassword
    {
        public ForgotPassword(string PQuestion)
        {
            this._Pquestion = PQuestion;
        }
        public ForgotPassword() { }
        [NotNullOrEmptyValidator(MessageTemplate = "Введите имя пользователя")]
        public string UserName { get; set; }
        private string _Pquestion;
        public string Pquestion { get { return this._Pquestion; } set { this._Pquestion = value; } }
        [NotNullOrEmptyValidator(MessageTemplate = "Введите ответ")]
        public string Panswer { get; set; }

        public string Password { get; set;}
    }
    
}